<!DOCTYPE html>
<html>
  <head>
    <!--Import Google Icon Font-->
    <link type="text/css" rel="stylesheet" href="css/material-icons.css"/>
    <!--Import materialize.css-->
    <link type="text/css" rel="stylesheet" href="css/materialize.min.css"  media="screen,projection"/>
    <title>Cell Status In Pool</title>

    <!--Let browser know website is optimized for mobile-->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <style>
    nav.clean{
        background: none;
        box-shadow: none;
    }

    .breadcrumb:before {
        color: rgba(0,0,0,0.7);
    }

    .breadcrumb, .breadcrumb:last-child {
       color: rgba(0,0,0,1);
    }
    </style>

  </head>
  <body>

  <div class="container">
    <div class="section">
      <nav class="clean">
         <div class="nav-wrapper">
           <div class="col s12">
              <a href="dashboard.html" class="breadcrumb" id="zone-caption"/>
              <a href="pool_status.html" class="breadcrumb" id="pool-caption"/>
              <a href="#" class="breadcrumb" id="bc-pool">default</a>
            </div>
        </div>
      </nav>
      <div class="divider"></div>
    </div>
    <div class="section" id="status_list">
    </div>
  </div>

  <!--JavaScript at end of body for optimized loading-->
  <script type="text/javascript" src="js/materialize.min.js"></script>
  <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
  <script type="text/javascript" src="js/Chart.bundle.min.js"></script>
  <script type="text/javascript" src="js/nano.js"></script>
  <script>
    N.ValidateSession();
    var texts = N.GetTexts();
    $('#zone-caption').text(texts.get(N.TagZone));
    $('#pool-caption').text(texts.get(N.TagComputePool));

    M.AutoInit();
    //get pool name
    var poolName;
    function getPoolName(){
      var url = window.location.search;
      var queryString = url.substring( url.indexOf('?') + 1 );
      if (0 === queryString.length){
        M.toast({html: 'no query string available', outDuration: 1500});
        return false;
      }
      var values = queryString.split("=");
      if (2 != values.length){
        M.toast({html: 'invalid query string', outDuration: 1500});
        return false;
      }
      if ('pool' != values[0]){
        M.toast({html: 'Must specify pool name', outDuration: 1500});
        return false;
      }
      poolName = values[1];
      return true;
    }


    var chartsMap = new Map();
    function addStatus(cellName){
      var cardTitle = $('<span>').addClass('card-title').text(cellName).prepend(
        $('<i>').addClass('material-icons blue-grey-text darken-2').text('view_quilt')
      );
      var canvasRow = $('<div>').addClass('row');
      var instanceCanvas = $('<canvas>', {id: 'instance_canvas_' + cellName}).attr('height', '320px');
      var coreCanvas = $('<canvas>', {id: 'core_canvas_' + cellName}).attr('height', '320px');
      var memoryCanvas = $('<canvas>', {id: 'memory_canvas_' + cellName}).attr('height', '320px');
      var diskCanvas = $('<canvas>', {id: 'disk_canvas_' + cellName}).attr('height', '320px');
      var ioCanvas = $('<canvas>', {id: 'io_canvas_' + cellName}).attr('height', '180px');

      canvasRow.append($('<div>').addClass('col m2').append(instanceCanvas));
      canvasRow.append($('<div>').addClass('col m2').append(coreCanvas));
      canvasRow.append($('<div>').addClass('col m2').append(memoryCanvas));
      canvasRow.append($('<div>').addClass('col m2').append(diskCanvas));
      canvasRow.append($('<div>').addClass('col m4').append(ioCanvas));


      var cardContent = $('<div>').addClass('card-content').append(cardTitle).append(canvasRow);
      var cardActions = $('<div>').addClass('card-action');
      cardActions.append($('<a>', {href: 'instance_status.html?cell='+ cellName + '&pool=' + poolName,  'data-position': 'bottom', 'data-tooltip': texts.get(N.TagInstance)}).addClass('blue-grey-text tooltipped').append(
        $('<i>').addClass('material-icons').text('cloud_queue')
      ));
      cardActions.append($('<a>', {href: 'monitor_cell_status.html?cell='+ cellName + '&pool=' + poolName,  'data-position': 'bottom', 'data-tooltip': texts.get(N.TagMonitor)}).addClass('blue-grey-text tooltipped').append(
        $('<i>').addClass('material-icons').text('insert_chart')
      ));
      var status = $('<div>', {id: 'status_' + cellName}).addClass('row').append(
        $('<div>').addClass('col m12 s12').append(
          $('<div>').addClass('card').append(cardContent).append(cardActions)
        )
      );
      $('#status_list').append(status);

      var instanceChart = new Chart(instanceCanvas,{
          type: "doughnut",
          data: {
            labels: [texts.get(N.TagStopped), texts.get(N.TagRunning), texts.get(N.TagLost), texts.get(N.TagMigrate)],
            datasets: [
              {
                backgroundColor: ['#9e9e9e', '#2196f3', "#ff9800", "#9e9e9e"],
              }
            ],
          },
          options: {
            cutoutPercentage: 70,
            legend: {
              display: false,
            },
            title: {
              display: true,
              text: texts.get(N.TagInstance)
            }
          }
      });
      //cpu canvas
      var coreChart = new Chart(coreCanvas, {
        type: "doughnut",
        data: {
          labels: [ texts.get(N.TagAvailable), texts.get(N.TagUsed)],
          datasets: [
            {
              backgroundColor: ['#bbdefb', '#2196f3'],
            }
          ],
        },
        options: {
          cutoutPercentage: 70,
          legend: {
            display: false,
          },
          title: {
            display: true,
            text: texts.get(N.TagCore)
          }
        }
      });
      //memory canvas
      var memoryChart = new Chart(memoryCanvas, {
        type: "doughnut",
        data: {
          labels: [ texts.get(N.TagAvailable), texts.get(N.TagUsed)],
          datasets: [
            {
              backgroundColor: ['#bbdefb', '#2196f3'],
            }
          ],
        },
        options: {
          cutoutPercentage: 70,
          legend: {
            display: false,
          },
          title: {
            display: true,
            text: texts.get(N.TagMemory)
          }
        }
      });
      var diskChart = new Chart( diskCanvas, {
        type: "doughnut",
        data: {
          labels: [ texts.get(N.TagAvailable), texts.get(N.TagUsed)],
          datasets: [
            {
              backgroundColor: ['#bbdefb', '#2196f3'],
            }
          ],
        },
        options: {
          cutoutPercentage: 70,
          legend: {
            display: false,
            // position: 'right',
          },
          title: {
            display: true,
            text: texts.get(N.TagDisk)
          }
        }
      });

      var ioChart = new Chart(ioCanvas, {
        type: "horizontalBar",
        data: {
          labels: [ texts.get(N.TagRead), texts.get(N.TagWrite), texts.get(N.TagReceive), texts.get(N.TagSend)],
          datasets: [
            {
              backgroundColor: ['#bbdefb', '#2196f3', '#c8e6c9', '#ffecb3'],
            }
          ],
        },
        options: {
          legend: {
            display: false,
          },
          title: {
            display: true,
            text: texts.get(N.TagIOMeter)
          },
          scales: {
            xAxes: [{
              display: true,
              scaleLabel: {
                display: true,
                labelString: 'MBytes/s'
              },
              ticks: {
                min: 0,
                max: 10,
                stepSize: 2,
              }
            }],
            yAxes: [{
              display: false,
            }],
          }
        }
      });

      var charts = {"instance": instanceChart, "core": coreChart, "memory": memoryChart, "disk": diskChart, "io": ioChart};
      chartsMap.set(cellName, charts);
      M.Tooltip.init($('.tooltipped'));
    }

    function updateChart(data){
      var cellName = data['name'];
      var charts = chartsMap.get(cellName);
      if(null == charts){
        M.toast({html: 'can not find chart for ' + cellName});
        return
      }
      var instanceChart = charts['instance'];
      var coreChart = charts['core'];
      var memoryChart = charts['memory'];
      var diskChart = charts['disk'];
      var ioChart = charts['io'];

      instanceChart.data.datasets[0].data = data['instances'];
      var idleCore = Math.floor(data['max_cpu'] * ( 100 - data['cpu_usage']))/100;
      var usedCore = Math.floor(data['cpu_usage'] * data['max_cpu'])/100;
      coreChart.data.datasets[0].data = [idleCore, usedCore];
      var mib = 1 << 20;
      var availableMemory = Math.floor(data['available_memory'] * 100 / mib) / 100;
      var usedMemory = Math.floor((data['max_memory'] - data['available_memory']) * 100 / mib) / 100;
      memoryChart.data.datasets[0].data = [availableMemory, usedMemory];
      var gib = 1 << 30;
      var availableDisk = Math.floor(data['available_disk'] * 100 / gib) / 100;
      var usedDisk = Math.floor((data['max_disk'] - data['available_disk']) * 100 / gib) / 100;
      diskChart.data.datasets[0].data = [availableDisk, usedDisk];

      ioChart.data.datasets[0].data = [Math.floor(data['read_speed'] * 100 / mib) / 100, Math.floor(data['write_speed'] * 100 / mib) / 100,
        Math.floor(data['receive_speed'] * 100 / mib) / 100, Math.floor(data['send_speed'] * 100 / mib) / 100];

      instanceChart.update();
      diskChart.update();
      coreChart.update();
      memoryChart.update();
      ioChart.update();
    }

    function updateDashboard(){
      $.getJSON("/compute_cell_status/" + poolName, function(result){
        if (0 != result['error_code']) {
            M.toast({html: 'update cell status fail:' + result['message']});
            return;
        }
        var clearTarget = new Set();
        for(var name of chartsMap.keys()){
          clearTarget.add(name);
        }
        result['data'].forEach((data) => {
          var cellName = data['name'];
          if (!chartsMap.has(cellName)){
            addStatus(cellName);
          }
          updateChart(data);
          if (clearTarget.has(cellName)){
            clearTarget.delete(cellName)
          }
        });
        clearTarget.forEach((cellName) =>{
          $('#status_' + cellName).remove();
          chartsMap.delete(cellName);
        });
      });
    }

    if (getPoolName()){
      $('#bc-pool').text(poolName);
      updateDashboard();
      setInterval(updateDashboard, 2000);
    }
  </script>
  </body>
</html>
